const Service = require('egg').Service;
const validateUtil = require('@jianghujs/jianghu/app/common/validateUtil');
const { BizError, errorInfoEnum } = require('../constant/error');
const { tableEnum } = require('../constant/constant');
const _ = require('lodash');
const dayjs = require('dayjs');
const idGenerateUtil = require("@jianghujs/jianghu/app/common/idGenerateUtil");


const actionDataScheme = Object.freeze({
  paymentIn: {
    type: 'object',
    additionalProperties: true,
    required: [ 'ticketId', 'ticketType', 'ticketContent', 'ticketStatus' ],
    properties: {
      ticketId: { anyOf: [{ type: "string" }, { type: "number" }] },
      ticketType: { type: "string", enum: ['保险付款', '保养付款', '退车付款', '发车收款'] },
      ticketContent: { type: 'object' },
      ticketStatus: { type: 'string', enum: ['处理中', '完成', '拒绝']},
    },
  },
 
  '保险付款': { 
    type: 'object',
  },
  '保养付款': { 
    type: 'object',
  },
  '退车付款': { 
    type: 'object',
  },
  '发车收款': { 
    type: 'object',
  },
});
class PaymentService extends Service {
  async getIdSequence({ table, startValue=1001 }) {
    const tableName = tableEnum[table];
    const columnName = "idSequence";
    const idSequence = await idGenerateUtil.idPlus({
      knex: this.app.jianghuKnex,
      tableName,
      columnName,
      startValue,
    });
    return idSequence;
  }

  async selectPaymentOrderList() {
    const { jianghuKnex } = this.app;
    const { ctx } = this;
    const actionData = this.ctx.request.body.appData.actionData;
    const { paymentId } = actionData;

    const paymentOrder = await jianghuKnex('payment_order').where({ paymentId }).select();
    const paymentOrderGroup = _.groupBy(paymentOrder, 'orderType');

    const orderConfig = {
      '保险订单': {'orderId': 'insuranceId', 'tableName': 'insurance'}, 
      '保养订单': {'orderId': 'maintenanceId', 'tableName': 'maintenance'},
      '发车订单': {'orderId': 'contractId', 'tableName': 'contract'},
      '退车订单': {'orderId': 'contractId', 'tableName': 'contract'},
    }

    const orderList = await Promise.all(_.map(orderConfig, async (value, key) => {
      const group = paymentOrderGroup[key];
      let list = [];
      if(group){
        const orderIds = _.map(group, 'orderId');
        list = await jianghuKnex(value['tableName']).whereIn([value['orderId']], orderIds).select();
      }
      return list;
    }))
    const flattenOrderList = _.flatten(orderList);

    const rows = _.map(paymentOrder, item => {
      const config = orderConfig[item.orderType];
      const order = _.find(flattenOrderList, o => o[config.orderId] === item.orderId);
      return {
        ...order,
        ...item,
      }
    })

    return { rows }
  }

  async paymentIn() {
    const { jianghuKnex, knex } = this.app;
    const { ctx } = this;
    const { userId, username } = ctx.userInfo;
    const actionData = this.ctx.request.body.appData.actionData;
    const { dataList } = actionData;

    //校验
    const ticketIds = _.map(dataList, 'ticketId');
    const ticketList = await jianghuKnex('ticket').whereIn('ticketId', ticketIds).select();
    if (ticketList.length !== dataList.length) {
      throw new BizError(errorInfoEnum.payment_ticket_request_not_exist);
    }
    if (_.find(ticketList, item => _.includes(['完成', '拒绝'], item.ticketStatus))) {
      throw new BizError(errorInfoEnum.payment_ticket_request_already_handle);
    }

    //处理数据
    let paymentInsertList = [];
    let orderUpdateList = [];
    let ticketUpdateList = [];
    const paymentOrderInsertList = [];
    let paymentIdSequence = await this.getIdSequence({ table: 'payment', startValue: 10001 });
    _.map(dataList, item => {
      const { ticketId, ticketBizId, ticketType, ticketContent, ticketStatus, ticketStatusDesc } = item;

      validateUtil.validate(actionDataScheme.paymentIn, item);
      validateUtil.validate(actionDataScheme[ticketType], ticketContent, '工单内容');

      if(ticketStatus === '完成'){
        const { accountInfo, paymentAmount, customerInfo } = ticketContent;
        const constant = {
          '保险付款': {orderType: '保险订单', orderId: 'insuranceId', paymentType: '付款'},
          '保养付款': {orderType: '保养订单', orderId: 'maintenanceId', paymentType: '付款'},
          '发车收款': {orderType: '发车订单', orderId: 'contractId', paymentType: '收款'},
          '退车付款': {orderType: '退车订单', orderId: 'contractId', paymentType: '付款'},
        }
        const paymentType = constant[ticketType].paymentType;
        const paymentId = 'P' + paymentIdSequence;

        let paymentInsert = {
          idSequence: paymentIdSequence,
          paymentId,
          paymentType,
          paymentAmount,

          paymentPayer: accountInfo.accountName,
          paymentPayerAccount: accountInfo.accountNum,
          paymentPayerBank: accountInfo.accountBankName,
          paymentPayerBranchBank: accountInfo.accountBranchBankName,
          paymentMethod: accountInfo.accountType,

          paymentAt: dayjs().format(),    


          paymentPayee: customerInfo.customerName,
          paymentPayeeAccount: customerInfo.customerAccountNum,
          paymentPayeeBank: customerInfo.customerBankName,
          paymentPayeeBranchBank: customerInfo.customerBranchBankName,
          customerId: customerInfo.customerId
        }


        //处理 payment 数据 
        paymentInsertList.push(paymentInsert) 

        //处理 payment_order 数据 
        paymentOrderInsertList.push({
          paymentId,
          paymentType,
          orderId: ticketContent[constant[ticketType].orderId],
          orderType: constant[ticketType].orderType,
          deductionAmount: paymentAmount,
        })


        // 订单更新数据
        const orderUpdateItem = {
          orderId: ticketBizId
        }
   
        switch (ticketType) {
          case '发车收款':
            orderUpdateItem.status = '已付押金'
            break;
          case '退车付款':
            orderUpdateItem.status = '已还押金'
            break;
          default:
            break;
        }
        orderUpdateList.push(orderUpdateItem)
        paymentIdSequence += 1;
      }

      //处理 ticket 数据 
      ticketUpdateList.push({
        ticketId,
        ticketContent: JSON.stringify(ticketContent), 
        ticketStatus, 
        ticketStatusDesc, 
        ticketStatusAt: dayjs().format(), 
        ticketStatusByUserId: userId, 
        ticketStatusByUser: username,
        ticketAmount: ticketContent.paymentAmount 
      })
    })

    //事务处理
    await jianghuKnex.transaction(async trx => {
      // payment 插入数据
      if(paymentInsertList.length > 0){
        await trx('payment').jhInsert(paymentInsertList);
      }

      // payment_order 插入数据
      if (paymentOrderInsertList.length > 0) {
        await trx('payment_order').jhInsert(paymentOrderInsertList)
      }


      //更新 ticket
      for(const item of ticketUpdateList){
        await trx('ticket').where({ ticketId: item.ticketId }).jhUpdate(item);
      }

      for(const item of orderUpdateList){
        await trx('order').where({ orderId: item.orderId, status: '已签约' }).jhUpdate(item);
      }
    });

    return '';
  }
}

module.exports = PaymentService;
